#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include "conhash.h"
struct flycache_cluster * fly_init()
{
	struct flycache_cluster *cluster; 
	cluster = malloc(sizeof (struct flycache_cluster));
	if (!cluster)
    {
        return NULL;
    }
	cluster->conhash = conhash_init(NULL);
	cluster->server_count = 0; 
	return cluster; 
}
int fly_free(struct flycache_cluster *cluster)
{
	conhash_fini(cluster->conhash); 
	return 0; 
}

int fly_add_server(struct flycache_cluster *cluster, char *ip, int port) 
{
	struct server_node_s *server_node; 
	server_node = malloc(sizeof (struct server_node_s));
	struct node_s *g_node; 
	g_node = malloc(sizeof (struct node_s));
	char iden[64]; 
	int sockfd, numbytes;
    char buf[BUFF_SIZE];
    char cmd[BUFF_SIZE];
    struct hostent *he;
    struct sockaddr_in their_addr;
    /*he = gethostbyname(ip);*/
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("socket create error");
		return -1; 
    }
	server_node->ip = ip;
	server_node->port=port; 
	server_node->sockfd=sockfd; 
	snprintf(iden, 64, "%s:%d", ip, port);
	conhash_set_node(g_node, iden, server_node, 50); 
	conhash_add_node(cluster->conhash, g_node); 

    their_addr.sin_family = AF_INET;
    their_addr.sin_port = htons(port);
	their_addr.sin_addr.s_addr = inet_addr(ip); 
    /*their_addr.sin_addr = *((struct in_addr *)he->h_addr);*/
    bzero(&(their_addr.sin_zero),8);
	if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1)
    {
        perror("connect error");
		return -1; 
    }
	cluster->server_count++; 
	printf("virtual nodes number %d\n", conhash_get_vnodes_num(cluster->conhash));
	printf("server number %d\n", cluster->server_count);
	return 0; 
		
}
int fly_del_server(struct flycache_cluster *cluster, char *ip, int port) 
{
	struct node_s *g_node; 
	g_node = malloc(sizeof (struct node_s));
	char iden[64]; 
	/*snprintf(iden, 64, "%s:%d", ip, port);*/
	/*conhash_set_node(g_node, iden, server_node, 50);*/
	/*conhash_del_node(g_node); */

	return 0; 
}

int fly_store(struct flycache_cluster *cluster,const char *key, int flag,int exptime, int length,const char * value)
{
	struct node_s *node; 
	int numbytes; 
	char cmd[BUFF_SIZE];
	char buf[BUFF_SIZE]; 
	snprintf(cmd, BUFF_SIZE, "set %s %d %d %d %s\r\n", key, flag, exptime, length, value);
	/*printf("%s", cmd); */
	node = conhash_lookup(cluster->conhash, key);
	if (send(node->server_node->sockfd,cmd, strlen(cmd), 0) == -1)
	{
		error("send error");
	}
	if (( numbytes = recv(node->server_node->sockfd, buf, BUFF_SIZE, 0)) == -1)
	{
		perror("recv error");
		return -1; 
	}
	buf[numbytes] = '\0';
	printf("%s\r\n",buf);
	
	return 0; 
}
char *fly_get(struct flycache_cluster *cluster,const char *key) 
{
	struct node_s *node;
	int numbytes; 
	char cmd[BUFF_SIZE];
	char buf[BUFF_SIZE]; 
	snprintf(cmd, BUFF_SIZE, "get %s\r\n", key);
	/*printf("%s", cmd); */
	node = conhash_lookup(cluster->conhash, key);
	if (send(node->server_node->sockfd,cmd, strlen(cmd), 0) == -1)
	{
		error("send error");
		return NULL; 
	}
	if (( numbytes = recv(node->server_node->sockfd, buf, BUFF_SIZE, 0)) == -1)
	{
		perror("recv error");
		return NULL; 
	}
	buf[numbytes] = '\0';
	/*printf("%s\r\n",buf);*/
	
	return buf; 
}

